﻿//using System;
//using ParserGenerator.Collections;
//using ParserGenerator.Exceptions;
//using ParserGenerator.Input;
//using ParserGenerator.LexicalAnalysis;
//using ParserGenerator.TypeExpressions;

//namespace ParserGenerator.Expressions
//{
//    [Serializable]
//    public class ExpressionValidator : ISequenceSliceValidator, IExpressionValidator
//    {
//        public TypeExpressionValidator TypeExpressionValidator { get; set; }

//        public virtual void ValidateComprehension(Comprehension n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Target, ExpressionUsage.Store);
//            ValidateExpression(n.Iterator);
//            ValidateExpressionList(n.Filters);
//        }

//        public virtual void ValidateComprehensionList(Sequence<Comprehension> list)
//        {
//            if (list == null)
//                throw new ArgumentNullException(nameof(list));
//            if (list.Count == 0)
//                throw new ValueErrorException(SR.ComprehensionWithNoGenerators);
//            foreach (Comprehension item in list)
//                ValidateComprehension(item);
//        }

//        public virtual void ValidateSequenceSlice(SequenceSlice n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            n.AcceptSequenceSliceValidator(this);
//        }

//        public virtual void ValidateRangeSequenceSlice(SequenceSlice.Range n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (n.Lower != null)
//                ValidateExpression(n.Lower);
//            if (n.Upper != null)
//                ValidateExpression(n.Upper);
//            if (n.Step != null)
//                ValidateExpression(n.Step);
//        }

//        private void AssertNotEmpty<T>(Sequence<T> list, string what, string owner)
//        {
//            if (list == null)
//                throw new ArgumentNullException(nameof(list));
//            if (what == null)
//                throw new ArgumentNullException(nameof(what));
//            if (owner == null)
//                throw new ArgumentNullException(nameof(owner));
//            if (list.Count == 0)
//            {
//                string message = string.Format(SR.EmptySequenceIn, what, owner);
//                throw new ValueErrorException(message);
//            }
//        }

//        public virtual void ValidateExtendedSequenceSlice(SequenceSlice.Extended n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            AssertNotEmpty(n.Dimensions, nameof(n.Dimensions), "ExtendedSlice");
//            foreach (SequenceSlice slice in n.Dimensions)
//                ValidateSequenceSlice(slice);
//        }

//        public virtual void ValidateIndexerSequenceSlice(SequenceSlice.Indexer n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Value);
//        }

//        public virtual void ValidateTypeAnnotation(Parameter n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (n.Type != null)
//                TypeExpressionValidator.ValidateTypeExpression(n.Type);
//        }

//        public virtual void ValidateTypeAnnotationList(Sequence<Parameter> list)
//        {
//            if (list == null)
//                throw new ArgumentNullException(nameof(list));
//            foreach (Parameter item in list)
//                ValidateTypeAnnotation(item);
//        }

//        public virtual void ValidateParameterList(ParameterList n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateTypeAnnotationList(n.Positional);
//            if (n.ExtraPositional != null && n.ExtraPositional.Type != null)
//                TypeExpressionValidator.ValidateTypeExpression(n.ExtraPositional.Type);
//            ValidateTypeAnnotationList(n.KeywordOnly);
//            if (n.ExtraKeywords != null && n.ExtraKeywords.Type != null)
//                TypeExpressionValidator.ValidateTypeExpression(n.ExtraKeywords.Type);
//            if (n.PositionalDefaults.Count > n.Positional.Count)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.FunctionHasTooManyDefaults);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//            if (n.KeywordOnlyDefaults.Count != n.KeywordOnly.Count)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.FunctionKWDefaultsMismatch);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//            ValidateExpressionList(n.PositionalDefaults);
//            ValidateExpressionList(n.KeywordOnlyDefaults, ExpressionUsage.Load, true);
//            CheckParameterCount(n);
//        }

//        public virtual void ValidateExpression(Expression n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n, ExpressionUsage.Load);
//        }

//        public virtual void ValidateExpression(Expression n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            bool checkUsage = true;
//            ExpressionUsage u = ExpressionUsage.Load;
//            switch (n.Tag)
//            {
//                case Expression.Category.Access:
//                    u = n.AsAccess.Usage;
//                    break;
//                case Expression.Category.Subscript:
//                    u = n.AsSubscript.Usage;
//                    break;
//                case Expression.Category.Starred:
//                    u = n.AsStarred.Usage;
//                    break;
//                case Expression.Category.NameReference:
//                    u = n.AsNameReference.Usage;
//                    break;
//                case Expression.Category.List:
//                    u = n.AsList.Usage;
//                    break;
//                case Expression.Category.Tuple:
//                    u = n.AsTuple.Usage;
//                    break;
//                case Expression.Category.ResultValueRef:
//                    u = n.AsResultValueRef.Usage;
//                    break;
//                case Expression.Category.ResultContextRef:
//                    u = n.AsResultContextRef.Usage;
//                    break;
//                case Expression.Category.SlotValueRef:
//                    u = n.AsSlotValueRef.Usage;
//                    break;
//                case Expression.Category.SlotContextRef:
//                    u = n.AsSlotContextRef.Usage;
//                    break;
//                default:
//                    if (usage != ExpressionUsage.Load)
//                    {
//                        string message = string.Format(SR.ExpressionCantBeAssignedInUsage, usage);
//                        SyntaxErrorException e = new SyntaxErrorException(message);
//                        e.AddLocation(n.Context);
//                        throw e;
//                    }
//                    checkUsage = false;
//                    u = ExpressionUsage.Load;
//                    break;
//            }
//            if (checkUsage && usage != u)
//            {
//                string message = string.Format(SR.ExpressionUsageMismatch, usage, u);
//                SyntaxErrorException e = new SyntaxErrorException(message);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//            n.AcceptExpressionValidator(this, usage);
//        }

//        public virtual void ValidateExpressionList(Sequence<Expression> items)
//        {
//            if (items == null)
//                throw new ArgumentNullException(nameof(items));
//            ValidateExpressionList(items, ExpressionUsage.Load, false);
//        }

//        public virtual void ValidateExpressionList(Sequence<Expression> items, ExpressionUsage usage)
//        {
//            if (items == null)
//                throw new ArgumentNullException(nameof(items));
//            ValidateExpressionList(items, usage, false);
//        }

//        public virtual void ValidateExpressionList(Sequence<Expression> items, ExpressionUsage usage, bool nullOk)
//        {
//            if (items == null)
//                throw new ArgumentNullException(nameof(items));
//            foreach (Expression e in items)
//            {
//                if (e != null)
//                    ValidateExpression(e, usage);
//                else if (!nullOk)
//                    throw new ValueErrorException(SR.NullPointerNotAllowedInExpressionList);
//            }
//        }

//        public virtual void ValidateNamedConstantExpression(Expression.NamedConstant n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateEllipsisExpression(Expression.Ellipsis n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateNumberExpression(Expression.Number n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            Constant value = n.Value;
//            switch (value.Tag)
//            {
//                case Constant.Category.Integer:
//                case Constant.Category.Float:
//                case Constant.Category.Complex:
//                    break;
//                default:
//                    SyntaxErrorException e = new SyntaxErrorException(SR.NonNumericTypeInNumberExpr);
//                    e.AddLocation(n.Context);
//                    throw e;
//            }
//        }

//        public virtual void ValidateStringExpression(Expression.String n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateByteStringExpression(Expression.ByteString n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateNameReferenceExpression(Expression.NameReference n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateThisRefExpression(Expression.ThisRef n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateBaseRefExpression(Expression.BaseRef n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateTypeRefExpression(Expression.TypeRef n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            TypeExpressionValidator.ValidateBuiltinTypeCode(n.Type);
//        }

//        public virtual void ValidateResultValueRefExpression(Expression.ResultValueRef n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateResultContextRefExpression(Expression.ResultContextRef n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateSlotValueRefExpression(Expression.SlotValueRef n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (n.Slot <= 0)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.StackSlotNumberMustBePositive);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//        }

//        public virtual void ValidateSlotContextRefExpression(Expression.SlotContextRef n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (n.Slot <= 0)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.StackSlotNumberMustBePositive);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//        }

//        public virtual void ValidateNewExpression(Expression.New n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            TypeExpressionValidator.ValidateTypeExpression(n.Type);
//            ValidatePositionalArgumentList(n.Arguments);
//            ValidateKeywordArgumentList(n.Keywords);
//            CheckArgumentCount(n.Arguments, n.Keywords, n.Context);
//        }

//        public virtual void ValidateDefaultExpression(Expression.Default n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            TypeExpressionValidator.ValidateTypeExpression(n.Type);
//        }

//        public virtual void ValidateTypeOfExpression(Expression.TypeOf n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            TypeExpressionValidator.ValidateTypeExpression(n.Type);
//        }

//        public virtual void ValidateNameOfExpression(Expression.NameOf n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Value);
//        }

//        public virtual void ValidateIsInstanceOfExpression(Expression.IsInstanceOf n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Value);
//            TypeExpressionValidator.ValidateTypeExpression(n.Type);
//        }

//        public virtual void ValidateAsInstanceOfExpression(Expression.AsInstanceOf n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Value);
//            TypeExpressionValidator.ValidateTypeExpression(n.Type);
//        }

//        public virtual void ValidateFStringItem(Expression n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            switch (n.Tag)
//            {
//                case Expression.Category.String:
//                    break;
//                case Expression.Category.Constant:
//                    if (!n.AsConstant.Value.IsString)
//                    {
//                        AssertionErrorException e = new AssertionErrorException(SR.FStringItemConstantMustBeString);
//                        e.AddLocation(n.Context);
//                        throw e;
//                    }
//                    break;
//                case Expression.Category.FormattedValue:
//                    ValidateExpression(n.AsFormattedValue.Value);
//                    if (n.AsFormattedValue.Conversion.HasValue)
//                    {
//                        switch (n.AsFormattedValue.Conversion.Value)
//                        {
//                            case 's':
//                            case 'r':
//                            case 'a':
//                                break;
//                            default:
//                                AssertionErrorException e = new AssertionErrorException(SR.InvalidConversionCode);
//                                e.AddLocation(n.Context);
//                                throw e;
//                        }
//                    }
//                    if (n.AsFormattedValue.Format != null)
//                        ValidateFStringItem(n.AsFormattedValue.Value);
//                    break;
//                case Expression.Category.JoinedString:
//                    foreach (Expression value in n.AsJoinedString.Values)
//                        ValidateFStringItem(value);
//                    break;
//                default:
//                    {
//                        AssertionErrorException e = new AssertionErrorException(SR.UnexpectedFStringItemType);
//                        e.AddLocation(n.Context);
//                        throw e;
//                    }
//            }
//        }

//        public virtual void ValidateFString(Expression n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateFStringItem(n);
//        }

//        public virtual void ValidateJoinedStringExpression(Expression.JoinedString n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateFString(n);
//        }

//        public virtual void ValidateFormattedValueExpression(Expression.FormattedValue n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateFString(n);
//        }

//        public virtual void ValidateConstantExpression(Expression.Constant n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//        }

//        public virtual void ValidateTupleExpression(Expression.Tuple n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpressionList(n.Elements, usage);
//        }

//        public virtual void ValidateListExpression(Expression.List n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpressionList(n.Elements, usage);
//        }

//        public virtual void ValidateSetExpression(Expression.Set n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpressionList(n.Elements);
//        }

//        public virtual void ValidateDictExpression(Expression.Dict n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (n.Keys.Count != n.Values.Count)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.DictExprKeyValueCountDiffer);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//            ValidateExpressionList(n.Keys, ExpressionUsage.Load, true);
//            ValidateExpressionList(n.Values);
//        }

//        public virtual void ValidateGeneratorExpression(Expression.Generator n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateComprehensionList(n.Comprehensions);
//            ValidateExpression(n.Element);
//        }

//        public virtual void ValidateListCompExpression(Expression.ListComp n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateComprehensionList(n.Comprehensions);
//            ValidateExpression(n.Element);
//        }

//        public virtual void ValidateSetCompExpression(Expression.SetComp n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateComprehensionList(n.Comprehensions);
//            ValidateExpression(n.Element);
//        }

//        public virtual void ValidateDictCompExpression(Expression.DictComp n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateComprehensionList(n.Comprehensions);
//            ValidateExpression(n.Key);
//            ValidateExpression(n.Value);
//        }

//        public virtual void ValidateYieldExpression(Expression.Yield n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (n.Value != null)
//                ValidateExpression(n.Value);
//        }

//        public virtual void ValidateYieldFromExpression(Expression.YieldFrom n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Value);
//        }

//        public virtual void ValidatePositionalArgumentList(Sequence<Expression> arguments)
//        {
//            if (arguments == null)
//                throw new ArgumentNullException(nameof(arguments));
//            ValidateExpressionList(arguments);
//        }

//        public virtual void ValidateKeywordArgumentList(Sequence<KeywordArgument> keywords)
//        {
//            if (keywords == null)
//                throw new ArgumentNullException(nameof(keywords));
//            foreach (KeywordArgument keyword in keywords)
//                ValidateExpression(keyword.Value);
//        }

//        public virtual void CheckArgumentCount(Sequence<Expression> arguments, Sequence<KeywordArgument> keywords, SourceContext context)
//        {
//            if (arguments == null)
//                throw new ArgumentNullException(nameof(arguments));
//            if (keywords == null)
//                throw new ArgumentNullException(nameof(keywords));
//            CheckArgumentCount(arguments, keywords, context, 0);
//        }

//        public virtual void CheckArgumentCount(Sequence<Expression> arguments, Sequence<KeywordArgument> keywords, SourceContext context, int pushed)
//        {
//            if (pushed + arguments.Count + keywords.Count > 255)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.CallExpressionHasTooManyArguments);
//                e.AddLocation(context);
//                throw e;
//            }
//        }

//        public virtual void ValidateCallExpression(Expression.Call n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Function);
//            ValidatePositionalArgumentList(n.Arguments);
//            ValidateKeywordArgumentList(n.Keywords);
//            CheckArgumentCount(n.Arguments, n.Keywords, n.Context);
//        }

//        public virtual void ValidateSubscriptExpression(Expression.Subscript n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateSequenceSlice(n.Slice);
//            ValidateExpression(n.Value);
//        }

//        public virtual void ValidateAccessExpression(Expression.Access n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Value);
//        }

//        public virtual void ValidateAwaitExpression(Expression.Await n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Value);
//        }

//        public virtual void ValidateUnaryExpression(Expression.Unary n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Operand);
//        }

//        public virtual void ValidateBinaryExpression(Expression.Binary n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Left);
//            ValidateExpression(n.Right);
//        }

//        public virtual void ValidateStarredExpression(Expression.Starred n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Value, usage);
//        }

//        public virtual void ValidateComparisonExpression(Expression.Comparison n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (n.Comparators.Count == 0)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.ComparisonWithNoComparators);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//            if (n.Operators.Count != n.Comparators.Count)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.ComparisonComparatorOperandNumMismatch);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//            ValidateExpression(n.Left);
//            ValidateExpressionList(n.Comparators);
//        }

//        public virtual void ValidateBooleanExpression(Expression.Boolean n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (n.Operands.Count < 2)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.BooleanExpressionOperandsNotEnough);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//        }

//        public virtual void ValidateIfExprExpression(Expression.IfExpr n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            ValidateExpression(n.Test);
//            ValidateExpression(n.Body);
//            ValidateExpression(n.OrElse);
//        }

//        public virtual void CheckParameterCount(ParameterList parameters)
//        {
//            if (parameters == null)
//                throw new ArgumentNullException(nameof(parameters));
//            if (parameters.Positional.Count + parameters.KeywordOnly.Count > 255)
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.FunctionHasTooManyParameters);
//                e.AddLocation(parameters.Context);
//                throw e;
//            }
//        }

//        public virtual void ValidateLambdaExpression(Expression.Lambda n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            CheckParameterCount(n.Parameters);
//            ValidateParameterList(n.Parameters);
//            ValidateExpression(n.Body);
//        }

//        public virtual void SetUsage(Expression n, ExpressionUsage usage)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            if (usage == ExpressionUsage.AugLoad || usage == ExpressionUsage.AugStore)
//            {
//                string message = string.Format(SR.ExpressionUsageNotSupported, usage);
//                ArgumentErrorException e = new ArgumentErrorException(message);
//                e.AddLocation(n.Context);
//                throw e;
//            }
//            switch (n.Tag)
//            {
//                case Expression.Category.Access:
//                    if (usage == ExpressionUsage.Store)
//                        CheckForbiddenName(n.AsAccess.Attribute, true);
//                    n.AsAccess.Usage = usage;
//                    break;
//                case Expression.Category.Subscript:
//                    n.AsSubscript.Usage = usage;
//                    break;
//                case Expression.Category.Starred:
//                    n.AsStarred.Usage = usage;
//                    SetUsage(n.AsStarred.Value, usage);
//                    break;
//                case Expression.Category.NameReference:
//                    if (usage == ExpressionUsage.Store)
//                        CheckForbiddenName(n.AsNameReference.Name);
//                    n.AsNameReference.Usage = usage;
//                    break;
//                case Expression.Category.List:
//                    n.AsList.Usage = usage;
//                    SetUsage(n.AsList.Elements, usage);
//                    break;
//                case Expression.Category.Tuple:
//                    if (n.AsTuple.Elements.Count == 0)
//                    {
//                        string doWhat = (usage == ExpressionUsage.Delete) ? "delete" : "assign to";
//                        string message = string.Format(SR.CanNotDeleteOrAssignTo, doWhat, "()");
//                        SyntaxErrorException e = new SyntaxErrorException(message);
//                        e.AddLocation(n.Context);
//                        throw e;
//                    }
//                    n.AsTuple.Usage = usage;
//                    SetUsage(n.AsTuple.Elements, usage);
//                    break;
//                case Expression.Category.ResultValueRef:
//                    n.AsResultValueRef.Usage = usage;
//                    break;
//                case Expression.Category.ResultContextRef:
//                    n.AsResultContextRef.Usage = usage;
//                    break;
//                case Expression.Category.SlotValueRef:
//                    n.AsSlotValueRef.Usage = usage;
//                    break;
//                case Expression.Category.SlotContextRef:
//                    n.AsSlotContextRef.Usage = usage;
//                    break;
//                default:
//                    {
//                        string doWhat = (usage == ExpressionUsage.Delete) ? "delete" : "assign to";
//                        string message = string.Format(SR.CanNotDeleteOrAssignTo, doWhat, n.Tag.ToString());
//                        SyntaxErrorException e = new SyntaxErrorException(message);
//                        e.AddLocation(n.Context);
//                        throw e;
//                    }
//            }
//        }

//        public virtual void SetUsageForAnnAssign(Expression n)
//        {
//            if (n == null)
//                throw new ArgumentNullException(nameof(n));
//            switch (n.Tag)
//            {
//                case Expression.Category.Access:
//                    CheckForbiddenName(n.AsAccess.Attribute, true);
//                    n.AsAccess.Usage = ExpressionUsage.Store;
//                    break;
//                case Expression.Category.Subscript:
//                    n.AsSubscript.Usage = ExpressionUsage.Store;
//                    break;
//                case Expression.Category.NameReference:
//                    CheckForbiddenName(n.AsNameReference.Name);
//                    n.AsNameReference.Usage = ExpressionUsage.Store;
//                    break;
//                case Expression.Category.List:
//                    {
//                        SyntaxErrorException e = new SyntaxErrorException(SR.ListCanNotBeAnnotated);
//                        e.AddLocation(n.Context);
//                        throw e;
//                    }
//                case Expression.Category.Tuple:
//                    {
//                        SyntaxErrorException e = new SyntaxErrorException(SR.TupleCanNotBeAnnotated);
//                        e.AddLocation(n.Context);
//                        throw e;
//                    }
//                default:
//                    {
//                        SyntaxErrorException e = new SyntaxErrorException(SR.IllegalAnnotationTarget);
//                        e.AddLocation(n.Context);
//                        throw e;
//                    }
//            }
//        }

//        public virtual void SetUsage(Sequence<Expression> list, ExpressionUsage usage)
//        {
//            if (list == null)
//                throw new ArgumentNullException(nameof(list));
//            foreach (Expression item in list)
//                SetUsage(item, usage);
//        }

//        public virtual void CheckForbiddenName(Name name)
//        {
//            if (name == null)
//                throw new ArgumentNullException(nameof(name));
//            CheckForbiddenName(name, false);
//        }

//        public virtual void CheckForbiddenName(Name name, bool fullCheck)
//        {
//            if (name == null)
//                throw new ArgumentNullException(nameof(name));
//            string n = name.Value;
//            if (n == "__debug__" || fullCheck && (n == "None" || n == "True" || n == "False"))
//            {
//                SyntaxErrorException e = new SyntaxErrorException(SR.AssignToKeyword);
//                e.AddLocation(name.Context);
//                throw e;
//            }
//        }
//    }
//}
